
package cz.czu.pef.DataModelling.beans;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.richfaces.model.selection.Selection;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import cz.czu.pef.DataModelling.Person;
import cz.czu.pef.DataModelling.beans.common.CalendarBean;
import cz.czu.pef.DataModelling.ejb.api.AbstractWrapperService;

@Component
@ViewScoped
@ManagedBean
public class PeopleBean extends AbstractExtendedTableBean<Person> implements ApplicationContextAware
{

	private static final long serialVersionUID = 7241568721878550809L;
	public static final Logger logger = Logger.getLogger(PeopleBean.class.getName());

	private ApplicationContext applicationContext;

	//@EJB (beanName="personServiceEJB", mappedName="personServiceEJB")
	@Autowired
	private AbstractWrapperService<Person> personServiceEJB;

	//@Autowired
	private Person person;
	private CalendarBean newPersonCalendar = new CalendarBean();

	protected PeopleBean()
	{
		super();
	}

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
	{
		this.applicationContext = applicationContext;
	}

	@PostConstruct
	public void create()
	{
		person = this.applicationContext.getBean(Person.class);
	}

	public Person getPerson()
	{
		return person;
	}


	public void setPerson(Person person)
	{
		this.person = person;
	}

	public CalendarBean getNewPersonCalendar()
	{
		return newPersonCalendar;
	}


	public void setNewPersonCalendar(CalendarBean newPersonCalendar)
	{
		this.newPersonCalendar = newPersonCalendar;
	}

	public PagingExtendedTableDataModel<Person> getItemsDataModel()
	{
		if (dataModel == null)
		{
			dataModel = new PagingExtendedTableDataModel<Person>(new PagingDataProvider<Person>()
				{

					private static final long serialVersionUID = 5054087821033164847L;

					public Person getItemByKey(Object key)
					{
						String myKey = key.toString();
						logger.finest("getItemByKey():: key=" + myKey);
						return personServiceEJB.getByStringId(myKey);
					}

					public List<Person> getItemsByRange(int firstRow, int endRow)
					{
						logger.finest("getItemsByRange():: firstRow(" + firstRow + "), endRow(" + endRow + ")");
						return personServiceEJB.findAllByRangeWithFilterAndSort(firstRow, endRow, getCustomFilterFields(), getCustomSortFields());
					}

					public Object getKey(Person item)
					{
						if (logger.isLoggable(Level.FINEST))
							logger.finest("getKey():: item=" + item);
						return item.getId();
					}

					public int getRowCount()
					{
						Long count = personServiceEJB.countWithFilter(getCustomFilterFields());
						logger.finest("getRowCount():: count=" + count);
						if (count != null)
							return count.intValue();
						return 0;
					}

				});
		}
		return dataModel;
	}

	public String createNew()
	{
		try
		{
			logger.finest("createNew():: Entry");
			/*
			FacesContext context = FacesContext.getCurrentInstance();
			//Person person = (Person)context.getApplication().evaluateExpressionGet(context, "#{person}", Person.class);
			Person newPerson = (Person) context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), "#{person}", Person.class).getValue(context.getELContext());
			*/

			logger.info("createNew():: person=" + person);
			if (person != null)
			{
				if (newPersonCalendar != null)
				{
					person.setBirthDate(newPersonCalendar.getSelectedDate());
				}
				if (person.getBirthDate() == null)
					person.setBirthDate(new Date());

				// persist new person
				personServiceEJB.merge(person);
			}

			// reset detail form's data
			person = this.applicationContext.getBean(Person.class);;
			newPersonCalendar = new CalendarBean(newPersonCalendar);

			return null;
		}
		finally
		{
			logger.finest("createNew():: Exit");

		}
	}

	@SuppressWarnings("rawtypes")
	public String removeSelected()
	{
		try
		{
			logger.finest("removeSelected():: Entry");
			/*
			FacesContext context = FacesContext.getCurrentInstance();
			//Person person = (Person)context.getApplication().evaluateExpressionGet(context, "#{person}", Person.class);
			Person newPerson = (Person) context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), "#{person}", Person.class).getValue(context.getELContext());
			*/

			Selection selectionForRemoval = getSelection();
			if (selectionForRemoval != null)
			{
				Iterator iter = selectionForRemoval.getKeys();
				while (iter.hasNext())
				{
					Object key = iter.next();
					logger.info("removeSelected():: Removing key=" + key.toString());
					Person person = personServiceEJB.getByStringId(key.toString());
					if (person != null)
					{
						if (personServiceEJB.canBeRemoved(person))
							personServiceEJB.deleteById(key.toString());
						else
							logger.warning("removeSelected():: Cannot remove person because of dependencies: " + person);
					}
					else
						logger.warning("removeSelected():: Cannot remove person because it's already removed: " + person);
				}

				setSelectedItems(new ArrayList<Person>());
			}

			return null;
		}
		finally
		{
			logger.finest("removeSelected():: Exit");
		}
	}

}
